import React, {useEffect, useRef, useState} from "react";
import {Dropdown, Space} from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { Enums, init as csRenderInit, RenderingEngine, imageLoader, metaData } from "@cornerstonejs/core";
import initCornerstoneDICOMImageLoader from '../utils/initCornerstoneDICOMImageLoaderT.js';
import {wadouri} from '@cornerstonejs/dicom-image-loader';
import * as cornerstoneTools from '@cornerstonejs/tools';
import './index.css';
import axios from "axios";

import dicomParser from 'dicom-parser';

import { saveAs } from 'file-saver';
import htmlDocx from 'html-docx-js/dist/html-docx';
import request from '../api/request.js'

import { Layout, Button, Input, Slider, Select, List, message, Upload, Spin, Image, Tabs, Form } from 'antd';
import { UploadOutlined } from '@ant-design/icons';


const { Header, Sider, Content } = Layout;

const {ViewportType, Events} = Enums;

const renderingEngineId = 'myRenderingEngine';
const viewportId = 'CT_STACK';

const windowWidth = 1500;
const windowCenter = -450;

const lower = windowCenter - windowWidth / 2.0;
const upper = windowCenter + windowWidth / 2.0;

const ctVoiRange = {lower, upper};

const tools = [
    {
        tool: cornerstoneTools.WindowLevelTool,
        name: cornerstoneTools.WindowLevelTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.PanTool,
        name: cornerstoneTools.PanTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.ZoomTool,
        name: cornerstoneTools.ZoomTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.StackScrollMouseWheelTool,
        name: cornerstoneTools.StackScrollMouseWheelTool.toolName
    },
    {
        tool: cornerstoneTools.LengthTool,
        name: cornerstoneTools.LengthTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.ProbeTool,
        name: cornerstoneTools.ProbeTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    }
];

const wwwcOptions = [
    { windowWidth: 1500, windowCenter: -450 }, // 原始窗
    { windowWidth: 1500, windowCenter: -600 }, // 肺窗
    { windowWidth: 1500, windowCenter: 300 }, // 骨窗
    { windowWidth: 350, windowCenter: 40 }, // 纵隔窗
    { windowWidth: 1700, windowCenter: -500 }, // 肺窗2
    { windowWidth: 400, windowCenter: 40 }, // 腹窗
    { windowWidth: 600, windowCenter: 300 }, // 血管造影
    { windowWidth: 80, windowCenter: 40 }, // 脑窗
  ];

const menuTools = [
    {
        label: '长度测量',
        key: cornerstoneTools.LengthTool.toolName,
    },
    {
        label: 'CT值测量',
        key: cornerstoneTools.ProbeTool.toolName,
    }
];

const columnNames = ["腺癌", "鳞癌", "炎症", "良性其他", "小细胞癌"];

let docImageData = {};

/**
 * demo按照file加载的模式
 */
function StackImages() {
    let isScrolling = false;

    let toolGroup = useRef(null);

    let pointRectShowStateRef = useRef('hidden');

    let docImageViewport = useRef(null);

    const [messageApi, contextHolder] = message.useMessage();

    const [uploadFileList, setUploadFileList] = useState([]);
    const uploadRef = useRef(null); // 使用 useRef 创建一个引用

    const [loading, setLoading] = React.useState(false);
    let txtRef = useRef(null);
    let sortDataRef = useRef(null);
    let maxColumnsRef = useRef([]);
    let csvFileRef = useRef([]);
    let [ctNumber, setCtNumber] = useState('');
    let imageIdref = useRef([]);
    let [dicom, setDicom] = useState([]);
    let [viewport, setViewport] = useState(null);
    let [dicomBasicInfo, setDicomBasicInfo] = useState(null);
    let [currentImageIdIndex, setCurrentImageIdIndex] = useState(0);
    let [currentCsvIndex, setCurrentCsvIndex] = useState(-1);
    let [pointRectShowState, setPointRectShowState] = useState('hidden');   // show hidden

    useEffect(() => {
        const content = document.getElementById('content');
        if (!content.children || (content.children.length === 0)) {
            setup();
        }
    }, []);

    useEffect(() => {
        pointRectShowStateRef.current = pointRectShowState;
    }, [pointRectShowState]);

    const setup = async () => {
        // dom
        const content = document.getElementById('content');
        const element = document.createElement('div');
        element.id = 'cornerstone-element';
        element.style.width = '100%';
        element.style.height = '100%';
        content.appendChild(element);

        // init
        initCornerstoneDICOMImageLoader();
        await csRenderInit({
            gpuTier: {
                tier: 0
            }
        });
        const renderingEngine = new RenderingEngine(renderingEngineId);
        const viewportInput = {
            viewportId,
            type: ViewportType.STACK,
            element
        };
        renderingEngine.enableElement(viewportInput);
        setViewport(renderingEngine.getViewport(viewportId));

        initTools();
    };

    

    const loadImageStack = async (imageIds) => {
        // stack render
        await viewport.setStack(imageIds);
        viewport.setProperties({voiRange: ctVoiRange});
        viewport.resize();
        viewport.render();

        // load dicom info
        const image = viewport.csImage;
        const patientName = image.data.string('x00100010') || 'N/A';
        const patientID = image.data.string('x00100020') || 'N/A';
        const patientAge = image.data.string('x00101010') || 'N/A';
        const patientSex = image.data.string('x00100040') || 'N/A';
        const patientStudyDate = image.data.string('x00080020') || 'N/A';
        setDicomBasicInfo({patientName, patientID, patientAge, patientSex, patientStudyDate});
        // add event listener
        viewport.element.addEventListener(Events.IMAGE_RENDERED, onImageRender);
        window.addEventListener('resize', handleResize);
    };

    const handleResize = () => {
        viewport.resize();
        viewport.render();
    };

    const parseTXT = (contents) => {
        const lines = contents.split('\n');
        const spacingLine = lines[0];
        const spacing = spacingLine.match(/Spacing=\(([^)]+)\)/)?.[1].split(',').map(Number) || [];
      
        const parsedData = {
          spacing: spacing,
          slices: [],
        };
      
        for (let i = 2; i < lines.length; i++) {
          const line = lines[i].trim();
          if (!line) {
            continue;
          }
          const [slice, leftX, leftY, rightX, rightY, centerPoint, width, height] = line.split(/\s+/);
          const [centerX, centerY] = centerPoint.replace(/[()]/g, '').split(',').map(Number);
      
          parsedData.slices.push({
            slice: Number(slice),
            leftX: Number(leftX),
            leftY: Number(leftY),
            rightX: Number(rightX),
            rightY: Number(rightY),
            centerPoint: { x: centerX, y: centerY },
            width: Number(width),
            height: Number(height),
          });
        }
      
        return parsedData;
      };
      
    const uploadTxt = async () => {
        try {
            await request({
                url: "/get_txt",
                method: "GET"
              }).then((res) => {
                console.log('txt', res);
                const text = res;
                const txt = parseTXT(text);
                txtRef.current = txt;
                // 从大到小排列
                // const sortedSlices = txt.slices.slice().sort((a, b) => b.slice - a.slice);
                sortDataRef.current = txt;
            });
        } catch (error) {
            message.error('结节信息请求发生错误①', error);
        }
    };
    
    // const uploadTxt = async () => {
    //     const text = `Spacing=(0.705078, 0.705078, 0.625)
    //     Slice		Left X		Left Y		Right X		Right Y		Center Point		Width(mm)		Height(mm)
    //     133			125				366				142				382				(133,374)				11.99				11.28
    //     139			306				363				319				376				(312,369)				9.17				9.17
    //     141			135				339				169				374				(152,356)				23.97				24.68
    //     147			156				331				168				343				(162,337)				8.46				8.46
    //     154			179				355				194				371				(186,363)				10.58				11.28
    //     160			108				366				120				379				(114,372)				8.46				9.17
    //     167			112				206				124				218				(118,212)				8.46				8.46
    //     173			114				354				138				378				(126,366)				16.92				16.92
    //     180			125				314				141				330				(133,322)				11.28				11.28
    //     181			205				329				215				339				(210,334)				7.05				7.05
    //     182			125				314				142				331				(133,322)				11.99				11.99
    //     187			131				314				147				329				(139,321)				11.28				10.58
    //     192			125				369				141				385				(133,377)				11.28				11.28
    //     194			137				311				155				329				(146,320)				12.69				12.69
    //     195			198				326				207				335				(202,330)				6.35				6.35
    //     196			399				270				410				281				(404,275)				7.76				7.76
    //     201			143				367				173				397				(158,382)				21.15				21.15
    //     205			111				380				122				391				(116,385)				7.76				7.76
    //     206			143				361				176				394				(159,377)				23.27				23.27
    //     210			101				370				114				383				(107,376)				9.17				9.17
    //     211			397				281				407				291				(402,286)				7.05				7.05
    //     229			391				296				402				307				(396,301)				7.76				7.76
    //     238			104				374				114				385				(109,379)				7.05				7.76
    //     250			150				181				161				192				(155,186)				7.76				7.76
    //     251			84				325				112				353				(98,339)				19.74				19.74
    //     260			91				329				112				350				(101,339)				14.81				14.81
    //     276			89				248				99				258				(94,253)				7.05				7.05
    //     282			94				346				105				357				(99,351)				7.76				7.76
    //     287			368				232				379				242				(373,237)				7.76				7.05
    //     288			90				253				98				261				(94,257)				5.64				5.64
    //     289			375				344				384				353				(379,348)				6.35				6.35
    //     293			104				250				123				269				(113,259)				13.40				13.40
    //     298			363				356				373				366				(368,361)				7.05				7.05
    //     308			94				330				105				341				(99,335)				7.76				7.76
    //     311			362				359				371				367				(366,363)				6.35				5.64
    //     317			360				362				368				370				(364,366)				5.64				5.64
    //     325			116				209				126				220				(121,214)				7.05				7.76
    //     333			376				261				385				269				(380,265)				6.35				5.64
    //     342			361				353				369				361				(365,357)				5.64				5.64
    //     363			293				389				303				398				(298,393)				7.05				6.35
    //     365			107				342				117				351				(112,346)				7.05				6.35
    //     367			316				378				327				389				(321,383)				7.76				7.76
    //     378			104				269				113				279				(108,274)				6.35				7.05
    //     384			147				220				164				238				(155,229)				11.99				12.69
    //     386			151				357				160				366				(155,361)				6.35				6.35
    //     388			108				279				120				291				(114,285)				8.46				8.46
    //     392			293				255				304				266				(298,260)				7.76				7.76
    //     394			347				273				355				281				(351,277)				5.64				5.64
    //     395			176				359				186				368				(181,363)				7.05				6.35
    //     398			296				259				308				271				(302,265)				8.46				8.46
    //     398			289				369				298				378				(293,373)				6.35				6.35
    //     401			345				305				356				316				(350,310)				7.76				7.76
    //     `;
    //     const txt = parseTXT(text);
    //     txtRef.current = txt;
    //     console.log('txtRef', txtRef.current);
    //     // 从大到小排列
    //     const sortedSlices = txt.slices.slice().sort((a, b) => b.slice - a.slice);
    //     sortDataRef.current = sortedSlices
    //     console.log('sortDataRef', sortDataRef.current);
    // };

    const uploadCsv = async () => {
        try {
            await request({
                url: "/get_csv",
                method: "GET"
              }).then((res) => {
                console.log('csv', res);
                const data = res;
                const trimmedData = data.slice(1, -1).map(row => row.slice(1));
                const formattedData = trimmedData.map(row => 
                    row.map(value => {
                        const num = Number(value);
                        return num.toFixed(10); // 使用 toFixed(10) 格式化为 10 位小数
                    })
                );
                csvFileRef.current = formattedData;
                const maxCols = trimmedData.map(row => {
                    let maxVal = Number.MIN_VALUE;
                    let maxIndex = -1;
                    row.forEach((value, index) => {
                    const floatValue = parseFloat(value);
                    if (floatValue > maxVal) {
                        maxVal = floatValue;
                        maxIndex = index;
                    }
                    });
                    return columnNames[maxIndex];
                });
                maxColumnsRef.current = maxCols;
            });
        } catch (error) {
            message.error('结节信息请求发生错误②', error);
        }
    }

    // const uploadCsv = async () => {
    //     const data = [
    //         [
    //             "",
    //             "0",
    //             "1",
    //             "2",
    //             "3",
    //             "4"
    //         ],
    //         [
    //             "0",
    //             "1.6814969e-05",
    //             "0.43286294",
    //             "0.02283739",
    //             "0.0020410111",
    //             "0.5422419"
    //         ],
    //         [
    //             "1",
    //             "4.036417e-09",
    //             "1.7340311e-05",
    //             "0.99996483",
    //             "1.7683313e-05",
    //             "1.6561458e-07"
    //         ],
    //         [
    //             "2",
    //             "1.4228116e-08",
    //             "0.9999912",
    //             "8.869274e-06",
    //             "4.5786347e-08",
    //             "1.7068161e-09"
    //         ],
    //         [
    //             "3",
    //             "2.321017e-05",
    //             "0.01246444",
    //             "0.0057162126",
    //             "0.0001157459",
    //             "0.9816804"
    //         ],
    //         [
    //             "4",
    //             "1.5739768e-09",
    //             "0.99934465",
    //             "0.0005997626",
    //             "1.1230688e-07",
    //             "5.5519457e-05"
    //         ],
    //         [
    //             "5",
    //             "2.9550876e-07",
    //             "1.2058941e-05",
    //             "0.99997854",
    //             "8.797439e-06",
    //             "2.199579e-07"
    //         ],
    //         [
    //             "6",
    //             "1.05599474e-10",
    //             "9.940225e-08",
    //             "0.99999917",
    //             "7.1892646e-07",
    //             "3.7564513e-10"
    //         ],
    //         [
    //             "7",
    //             "0.00083699386",
    //             "0.0012350312",
    //             "0.06227878",
    //             "0.0024935803",
    //             "0.9331556"
    //         ],
    //         [
    //             "8",
    //             "0.00018770141",
    //             "0.27095932",
    //             "0.72270036",
    //             "0.0022265248",
    //             "0.0039260658"
    //         ],
    //         [
    //             "9",
    //             "6.6773265e-07",
    //             "0.0032102289",
    //             "0.9842163",
    //             "0.00013586601",
    //             "0.01243702"
    //         ],
    //         [
    //             "10",
    //             "4.3346344e-09",
    //             "0.037742857",
    //             "0.9619102",
    //             "0.00033991513",
    //             "7.130691e-06"
    //         ],
    //         [
    //             "11",
    //             "0.0020356115",
    //             "1.1486971e-07",
    //             "0.9979632",
    //             "1.1022208e-06",
    //             "1.5675788e-10"
    //         ],
    //         [
    //             "12",
    //             "1.6921776e-05",
    //             "0.010991031",
    //             "0.90685916",
    //             "0.0821307",
    //             "2.073783e-06"
    //         ],
    //         [
    //             "13",
    //             "1.2162776e-07",
    //             "0.0716641",
    //             "0.92163837",
    //             "0.006696645",
    //             "7.078917e-07"
    //         ],
    //         [
    //             "14",
    //             "6.550712e-08",
    //             "9.46346e-05",
    //             "0.9985669",
    //             "0.0013205705",
    //             "1.7685727e-05"
    //         ],
    //         [
    //             "15",
    //             "3.4394177e-06",
    //             "0.036842976",
    //             "0.9585933",
    //             "0.0045596357",
    //             "7.021428e-07"
    //         ],
    //         [
    //             "16",
    //             "4.392215e-09",
    //             "2.707672e-05",
    //             "0.9997949",
    //             "0.00017798538",
    //             "7.401332e-08"
    //         ],
    //         [
    //             "17",
    //             "1.2025005e-05",
    //             "0.00027774766",
    //             "0.9987538",
    //             "0.00050920097",
    //             "0.00044723487"
    //         ],
    //         [
    //             "18",
    //             "7.2057315e-07",
    //             "0.1268924",
    //             "0.87308776",
    //             "1.6937978e-05",
    //             "2.206866e-06"
    //         ],
    //         [
    //             "19",
    //             "1.320332e-11",
    //             "1.1158376e-06",
    //             "0.999992",
    //             "5.5856613e-06",
    //             "1.2540853e-06"
    //         ],
    //         [
    //             "20",
    //             "2.4150168e-07",
    //             "6.223118e-05",
    //             "0.9999368",
    //             "5.44971e-07",
    //             "1.3056595e-07"
    //         ],
    //         [
    //             "21",
    //             "0.06883021",
    //             "5.9849896e-07",
    //             "0.9310445",
    //             "1.1143009e-05",
    //             "0.00011350802"
    //         ],
    //         [
    //             "22",
    //             "1.0339564e-10",
    //             "2.2195454e-11",
    //             "1.0",
    //             "1.2501976e-10",
    //             "2.0061217e-11"
    //         ],
    //         [
    //             "23",
    //             "0.3112519",
    //             "0.111242846",
    //             "0.5742363",
    //             "8.397268e-06",
    //             "0.0032605517"
    //         ],
    //         [
    //             "24",
    //             "9.183655e-12",
    //             "4.373214e-06",
    //             "0.99999547",
    //             "1.1820578e-07",
    //             "2.9485376e-08"
    //         ],
    //         [
    //             "25",
    //             "0.063635185",
    //             "0.0011994401",
    //             "0.93355274",
    //             "0.0010243682",
    //             "0.000588271"
    //         ],
    //         [
    //             "26",
    //             "0.035461005",
    //             "0.00031678742",
    //             "0.9562363",
    //             "0.006350085",
    //             "0.0016358197"
    //         ],
    //         [
    //             "27",
    //             "9.685837e-06",
    //             "4.331404e-05",
    //             "0.9999291",
    //             "3.4848897e-06",
    //             "1.4465034e-05"
    //         ],
    //         [
    //             "28",
    //             "2.099777e-10",
    //             "2.5912941e-08",
    //             "0.99999964",
    //             "3.070702e-07",
    //             "2.0386954e-12"
    //         ],
    //         [
    //             "29",
    //             "5.7630425e-09",
    //             "0.5574112",
    //             "0.44258574",
    //             "1.378635e-08",
    //             "3.0851834e-06"
    //         ],
    //         [
    //             "30",
    //             "1.3317162e-05",
    //             "0.0040751314",
    //             "0.99577713",
    //             "7.1872223e-06",
    //             "0.00012718521"
    //         ],
    //         [
    //             "31",
    //             "3.233159e-11",
    //             "6.8711124e-05",
    //             "0.99993086",
    //             "3.070438e-07",
    //             "1.00560584e-07"
    //         ],
    //         [
    //             "32",
    //             "7.577764e-07",
    //             "0.0061870716",
    //             "0.99363637",
    //             "1.2203771e-05",
    //             "0.00016361011"
    //         ],
    //         [
    //             "33",
    //             "0.042243283",
    //             "0.0013160158",
    //             "0.955824",
    //             "3.2158567e-07",
    //             "0.0006163708"
    //         ],
    //         [
    //             "34",
    //             "7.316305e-06",
    //             "0.0027127536",
    //             "0.984641",
    //             "0.00025278615",
    //             "0.01238595"
    //         ],
    //         [
    //             "35",
    //             "0.05507427",
    //             "0.006295434",
    //             "0.8531958",
    //             "0.060569566",
    //             "0.02486494"
    //         ],
    //         [
    //             "36",
    //             "1.7089425e-08",
    //             "0.21243438",
    //             "0.7857461",
    //             "0.0018193995",
    //             "1.2503696e-07"
    //         ],
    //         [
    //             "37",
    //             "4.6065367e-07",
    //             "1.3420997e-05",
    //             "0.9999721",
    //             "1.3295134e-05",
    //             "7.408453e-07"
    //         ],
    //         [
    //             "38",
    //             "2.0497325e-06",
    //             "3.2214193e-05",
    //             "0.99991226",
    //             "4.5370627e-05",
    //             "8.150354e-06"
    //         ],
    //         [
    //             "39",
    //             "0.15526472",
    //             "0.0024801588",
    //             "0.4190123",
    //             "0.013555134",
    //             "0.4096876"
    //         ],
    //         [
    //             "40",
    //             "0.20300671",
    //             "0.0018908026",
    //             "0.17765667",
    //             "0.004234813",
    //             "0.61321104"
    //         ],
    //         [
    //             "41",
    //             "0.99400216",
    //             "6.669488e-07",
    //             "3.6939033e-05",
    //             "0.0039025578",
    //             "0.0020575626"
    //         ],
    //         [
    //             "42",
    //             "0.0014388559",
    //             "0.0021009732",
    //             "0.92007995",
    //             "0.033212345",
    //             "0.04316783"
    //         ],
    //         [
    //             "43",
    //             "4.1485382e-07",
    //             "1.952866e-05",
    //             "0.9989987",
    //             "0.0008565125",
    //             "0.00012496597"
    //         ],
    //         [
    //             "44",
    //             "1.6020988e-11",
    //             "0.000615011",
    //             "0.9993832",
    //             "9.931163e-07",
    //             "8.693686e-07"
    //         ],
    //         [
    //             "45",
    //             "3.054208e-08",
    //             "0.0011106402",
    //             "0.99888355",
    //             "8.043636e-08",
    //             "5.755829e-06"
    //         ],
    //         [
    //             "46",
    //             "5.8688926e-10",
    //             "5.218448e-06",
    //             "0.99999475",
    //             "4.0536174e-10",
    //             "2.9005007e-10"
    //         ],
    //         [
    //             "47",
    //             "4.2078952e-08",
    //             "0.98269236",
    //             "0.017302107",
    //             "3.7244101e-06",
    //             "1.7120617e-06"
    //         ],
    //         [
    //             "48",
    //             "0.00026105586",
    //             "0.31980792",
    //             "0.54654366",
    //             "0.117652215",
    //             "0.015735166"
    //         ],
    //         [
    //             "49",
    //             "6.0087248e-12",
    //             "1.7748861e-11",
    //             "1.0",
    //             "1.346169e-10",
    //             "2.2188965e-12"
    //         ],
    //         [
    //             "50",
    //             "0.68593013",
    //             "0.0077484753",
    //             "0.18774375",
    //             "0.07958302",
    //             "0.038994662"
    //         ],
    //         [
    //             "51",
    //             "1.5326761e-09",
    //             "0.9873876",
    //             "0.012477208",
    //             "0.00011005674",
    //             "2.515005e-05"
    //         ],
    //         [
    //             "52",
    //             "0.9517833",
    //             "1.9224217e-06",
    //             "0.046398956",
    //             "0.0018156485",
    //             "2.170264e-07"
    //         ]
    //     ];
    //     const trimmedData = data.slice(1, -1).map(row => row.slice(1));
    //     const formattedData = trimmedData.map(row => 
    //         row.map(value => {
    //             const num = Number(value);
    //             return num.toFixed(10); // 使用 toFixed(6) 格式化为 6 位小数
    //         })
    //     );
    //     console.log(trimmedData);
    //     csvFileRef.current = formattedData;
    //     const maxCols = formattedData.map(row => {
    //         let maxVal = Number.MIN_VALUE;
    //         let maxIndex = -1;
    //         row.forEach((value, index) => {
    //         const floatValue = parseFloat(value);
    //         if (floatValue > maxVal) {
    //             maxVal = floatValue;
    //             maxIndex = index;
    //         }
    //         });
    //         return columnNames[maxIndex];
    //     });
    //     console.log("maxColumn", maxCols);
    //     maxColumnsRef.current = maxCols;
    // }


    const onImageRender = () => {
        setCurrentImageIdIndex(viewport.currentImageIdIndex);
        if (pointRectShowStateRef.current === 'show') {
            drawRect();
        }
        isScrolling = false;
    };

    const initTools = () => {
        tools.forEach((v) => {
            cornerstoneTools.addTool(v.tool);
        })
        toolGroup.current = cornerstoneTools.ToolGroupManager.createToolGroup('myToolGroup');
        tools.forEach((v) => {
            toolGroup.current.addTool(v.name);
        })
        // 左键
        tools.forEach((v) => {
            if (v.mouse) {
                // 包含鼠标事件的工具
                toolGroup.current.setToolActive(v.name, {
                    bindings: [{mouseButton: v.mouse}]
                });
            } else {
                toolGroup.current.setToolActive(v.name);
            }
        })
        toolGroup.current.addViewport(viewportId, renderingEngineId);
    };

    const handleToolMenuClick = (info) => {
        tools.forEach((v) => {
            if (v.mouse && (v.mouse === cornerstoneTools.Enums.MouseBindings.Primary)) {
                toolGroup.current.setToolPassive(v.name);
            }
        })
        toolGroup.current.setToolActive(info.key, {
            bindings: [{mouseButton: cornerstoneTools.Enums.MouseBindings.Primary}]
        });
    };

    const toggleShowRect = () => {
        const next = pointRectShowState === 'show' ? 'hidden' : 'show';
        setPointRectShowState(next);
        if (next === 'show') {
            drawRect();
        } else {
            viewport.render();
        }
    };

    const drawRect = () => {
        if (!viewport) return;
        const context = viewport.canvas.getContext('2d');
        const slices = txtRef.current.slices;
        for(let i = 0; i < slices.length; i ++) {
            const item = slices[i];
            const slice = item.slice;
            const leftX = item.leftX;
            const leftY = item.leftY;
            const rightX = item.rightX;
            const rightY = item.rightY;
            if (slice === viewport.currentImageIdIndex) {
                context.strokeStyle = 'rgba(41, 198, 33, 1)';
                context.fillStyle = 'rgba(41, 198, 33, 1)';
                // 计算矩形的宽度和高度
                const width = Math.abs(leftX - rightX);
                const height = Math.abs(leftY - rightY);
                context.strokeRect(leftX, leftY, width, height)
                context.textAlign = 'left';
                context.font = '15px serif';
                context.fillText(maxColumnsRef.current[i], rightX + 3, rightY);
            }
        }
    };

    const handleWWWC = (value) => {
        // wwwcOptions
        const lower = wwwcOptions[value].windowCenter - wwwcOptions[value].windowWidth / 2.0;
        const upper = wwwcOptions[value].windowCenter + wwwcOptions[value].windowWidth / 2.0;

        const ctVoiRange = {lower, upper};
        viewport.setProperties({voiRange: ctVoiRange})
        viewport.render();
    }

    
    const goToPage = (targetIndex) => {
        // Ensure that targetIndex is within valid range
        if (targetIndex < 0 || targetIndex >= viewport.imageIds.length) {
            return;
        }
        if (!viewport) return ;
        if (isScrolling) return ;
        if (targetIndex === viewport.currentImageIdIndex) return;
        isScrolling = true;
        const currentIndex = viewport.currentImageIdIndex;
        const delta = targetIndex - currentIndex;
        // 创建滚动选项对象
        const options = {
            delta: delta, // 滚动的增量
        };
        try {
            cornerstoneTools.utilities.scroll(viewport, options);
        } catch (error) {
            console.error('Error while scrolling:', error);
        }
    }

    const onClickpdf = async () => {
        // 创建包含图像的 HTML 字符串
        let htmlString = `
        <!DOCTYPE html>
        <html>
        <head>
            <style>
            body {
                font-family: Arial, sans-serif;
            }
            h1 {
                font-size: 30px;
                text-align: center;
            }
            h3 {
                text-align: center;
            }
            hr {
                border: 1px solid #000;
            }
            .patient-info {
                font-size: 14px;
            }
              .hr-dashed-fixed {
                border: 0;
                padding-top: 1px;
                /* for IE浏览器 */
                background: repeating-linear-gradient(to right, #a2a9b6 0px, #a2a9b6 4px, transparent 0px, transparent 10px);
                /* for 现代浏览器 */
                background: repeating-linear-gradient(to right, #a2a9b6 0 var(--dashed-filled, 4px), transparent 0 calc(var(--dashed-filled, 4px) + var(--dashed-open, 6px)));//传入变量来定义疏密
            }
            </style>
        </head>
        <body>
            <h1>肺部CT报告</h1>
            <hr class="hr-dashed-fixed" style="--dashed-filled: 8px; --dashed-open: 4px;"/>
            <div class="patient-info">
            <p>ID: ${dicomBasicInfo.patientID}</p>
            <p>姓名: ${dicomBasicInfo.patientName}</p>
            <p>年龄: ${dicomBasicInfo.patientAge}</p>
            <p>性别: ${dicomBasicInfo.patientSex}</p>
            <p>检查日期: ${dicomBasicInfo.patientStudyDate}</p>
            </div>
          <hr class="hr-dashed-fixed" style="--dashed-filled: 8px; --dashed-open: 4px;"/>
          <h3>
            报告详情
          </h3>
          `

        // 加入图片
        const docImages = await getDocImages();
        console.log('docImages', docImages);
        console.log('sortData', sortDataRef.current);
        console.log('csvFile', csvFileRef.current);
        
        // Create a map to store the corresponding sortData and maxColumns for each image
        const imageDataMap = new Map();

        for (let i = 0; i < sortDataRef.current.length; i++) {
            const item = sortDataRef.current[i];
            const imageId = item.slice; // 假设 sortData 中有 imageId 属性与 docImages 对应
            let probabilitiesString = "";

            if (!imageDataMap.has(imageId)) {
                imageDataMap.set(imageId, []);
            }
            const selectedData = csvFileRef.current[i];
            for (let j = 0; j < selectedData.length; j++) {
                probabilitiesString += `${columnNames[j]}: ${selectedData[j]}<br/>`;
            }
            
            imageDataMap.get(imageId).push({
                description: maxColumnsRef.current[i],
                width: item.width,
                height: item.height,
                probabilities: probabilitiesString
            });
        }
        console.log("imageDataMap", imageDataMap);

        for (let i = 0; i < docImages.length; i++) {
            const imageItem = docImages[i];
            // const len = viewport.imageIds.length
            const imageId = imageItem.slice; // 假设 docImages 中有 id 属性
            const imageData = imageDataMap.get(imageId) || [];
            console.log('i', i, imageItem, imageData);
        
            htmlString += `<img src="${imageItem.image}" alt="CT Image"/>`;
        
            for (let j = 0; j < imageData.length; j++) {
                const data = imageData[j];
                htmlString += `
                    <p>描述：${data.description} ${data.width}mm × ${data.height}mm
                    <br />
                    其他概率：${data.probabilities}
                    </p>
                    <br/>
                `;
            }
        }

        // 结尾
        htmlString += `
        <h4>影像所见：</h4>
        <br/>
        <h4>防范建议：</h4>
        <br/>
        </body>
        </html>
        `;
        // 使用 html-docx-js 将 HTML 字符串转换为 DOCX
        const blob = htmlDocx.asBlob(htmlString);
        saveAs(blob, `${dicomBasicInfo.patientID}肺部CT报告.docx`);
        
    }

    const onDocImageRender = () => {
        const context = docImageViewport.value.canvas.getContext('2d');
        const page = docImageViewport.value.currentImageIdIndex;
        for (let i = 0; i < sortDataRef.current.length; i++) {
            if (page === sortDataRef.current[i].slice)
            {
                const { leftX, leftY, rightX, rightY } = sortDataRef.current[i];
                context.strokeStyle = 'rgba(41, 198, 33, 1)';
                context.fillStyle = 'rgba(41, 198, 33, 1)';
                const width = Math.abs(leftX - rightX);
                const height = Math.abs(leftY - rightY);
                context.strokeRect(leftX, leftY, width, height);
            }
        }
        const data = docImageViewport.value.canvas.toDataURL('image/png');
        docImageData.resolve(data);
    }

    const getOneDocImage = (item) => {
        return new Promise(async (resolve, reject) => {
            docImageData = {
                resolve,
                data: null
            };
            docImageViewport.value.setImageIdIndex(item.slice);
            // drawRect(item.slice
            await drawRectSingle(item);
        })
    }

    const drawRectSingle = (item) => {
        const context = docImageViewport.value.canvas.getContext('2d');
        const slice = item.slice;
        const leftX = item.leftX;
        const leftY = item.leftY;
        const rightX = item.rightX;
        const rightY = item.rightY;
        if (slice === viewport.currentImageIdIndex) {
            context.strokeStyle = 'rgba(41, 198, 33, 1)';
            context.fillStyle = 'rgba(41, 198, 33, 1)';
            // 计算矩形的宽度和高度
            const width = Math.abs(leftX - rightX);
            const height = Math.abs(leftY - rightY);
            context.strokeRect(leftX, leftY, width, height)
            // context.textAlign = 'left';
            // context.font = '15px serif';
            // context.fillText(maxColumnsRef.current[item.index], rightX + 3, rightY);
        }
    }

    const getDocImages = () => {
        return new Promise(async (resolve, reject) => {
            const curFiles = dicom;
            const imageIds = [];
            for (let i = 0; i < curFiles.length; i++) {
                imageIds[i] = wadouri.fileManager.add(curFiles[i]);
            }
            const element = document.createElement('div');
            element.id = 'cornerstone-element-doc';
            element.style.width = '350px';
            element.style.height = '350px';
            element.style.visible = 'hidden';
            document.body.appendChild(element);
            const viewportId = 'CT_Stack_doc';
            const renderingEngine = new RenderingEngine("RenderingEngineDoc");
            const viewportInput = {
                viewportId,
                type: ViewportType.STACK,
                element
            };
            renderingEngine.enableElement(viewportInput);
            docImageViewport.value = renderingEngine.getViewport(viewportId);
            docImageViewport.value.element.addEventListener(Events.IMAGE_RENDERED, onDocImageRender);
            docImageViewport.value.setStack(imageIds);
            docImageViewport.value.setProperties({voiRange: ctVoiRange});

            const slices = sortDataRef.current;
            const result = [];
            const processedSlices = new Set();  // 用于跟踪已处理的slice页码
            for (let i = 0; i < slices.length; i++) {
                const item = slices[i];
                // 如果当前slice页码已处理，则跳过
                if (processedSlices.has(item.slice)) {
                    continue;
                }
                const image = await getOneDocImage(item);
                result.push({
                    index: i,
                    slice: item.slice,
                    image
                })
                // 标记当前slice页码为已处理
                processedSlices.add(item.slice);
            }
            docImageViewport.value.element.removeEventListener(Events.IMAGE_RENDERED, onDocImageRender);
            document.body.removeChild(element);
            resolve(result);
        })
    }

    const handleListItemClick = (item, index) => {
        setCurrentCsvIndex(index);
        goToPage(item.slice)
    }

    const parseDicomFile = (arrayBuffer) => {
        let result = 0;
        try {
          const byteArray = new Uint8Array(arrayBuffer);
          const dataSet = dicomParser.parseDicom(byteArray);
          const instanceNumber = dataSet.string('x00200013');
          result = instanceNumber;
        } catch (error) {
          console.error('Error parsing DICOM file:', error);
        //   setSeriesInstanceUID(null);
        }
        return result;
      };
    

    const onFileChange = async (event) => {
        // 先按照seriesInstance排序
        const file = event.target.files;
        if (!file) {
            return;
        }
        // 存储每个文件的 Instance Number 和文件本身
        const filesWithInstanceNumbers = [];
        for (let i = 0; i < file.length; i++) {
            const reader = new FileReader();
            const curFile = file[i];
            reader.onload = async (event) => {
                const arrayBuffer = event.target.result;
                const instanceNumber = parseDicomFile(arrayBuffer);
                filesWithInstanceNumbers.push({ instanceNumber, file: curFile });

                // 如果已经处理完所有文件，则进行排序和获取文件列表
                if (filesWithInstanceNumbers.length === file.length) {
                    // 按 Instance Number 属性从小到大排序
                    filesWithInstanceNumbers.sort((a, b) => a.instanceNumber - b.instanceNumber);

                    // 获取排序后的文件列表
                    const sortedFiles = filesWithInstanceNumbers.map(item => item.file);

                    setDicom(sortedFiles);

                    const imageIds = [];
                    for (let i = 0; i < sortedFiles.length; i++) {
                        imageIds[i] = wadouri.fileManager.add(sortedFiles[i]);
                    }
                    loadImageStack(imageIds);
                }
            };
            reader.readAsArrayBuffer(curFile);
        }
    };
    
      const renderReportContent = () => {
        if (!csvFileRef.current) {
            return ;
        }
        let i = currentCsvIndex;
        if (i === -1) {
            return ;
        }
        const selectedData = csvFileRef.current[currentCsvIndex];

        return (
            <div>
                <p>描述：{maxColumnsRef.current[i]} {sortDataRef.current[i].width}mm × {sortDataRef.current[i].height}mm
                <br />
                其他概率：
                {
                selectedData.map((value, i) => (
                    <div key={i}>{columnNames[i]}: {value}</div>
                ))}
                </p>
                {/* 其他内容 */}
            </div>
        );
    };

    const handleReset = () => {
        viewport.setProperties({voiRange: ctVoiRange});
        viewport.resetCamera();
        viewport.render();
    };

    const handleSubmit = async (values) => {
        setLoading(true);
        let accessionNumber = values.ctNumber
        console.log(values);

        try {
          const requestData = {
            accessionNumber: accessionNumber,
          };
          await axios.post('/api/queryAndRetrieve', requestData, {
            headers: {
              'Content-Type': 'application/json',
            }
          });

          const url = `/api/downloadDicom`
          const params = {
            accessionNumber: accessionNumber,
            destinationPath: '/data/test/data/origin/2654624/DICOM/'
          }
          await axios.get(url, {params});

          getFile();

          //从后端请求中获取到studyUID, seriesUID, ObjectUID
          await request({
            url: "/dicom-data",
            method: "GET",
            params: {
                accessionNumber: accessionNumber,
            }
          }).then(async (res) => {
            console.log('/dicom-data', res);
            let studyUID = res.studies;
            let seriesUID = res.series;
            let instanceUIDs = res.instances;
            // 创建一个Promise数组来处理所有的异步操作
            const promises = instanceUIDs.map(async instance => {
                // let imageURL = `/server/wado?requestType=WADO&studyUID=${studyUID}&seriesUID=${seriesUID}&objectUID=${instance}&contentType=application/dicom`;
                await request({
                    url: "/downloadsigle",
                    method: "GET",
                    params: {
                        url: `http://10.1.209.4:8042/wado?requestType=WADO&studyUID=${studyUID}&seriesUID=${seriesUID}&objectUID=${instance}&contentType=application/dicom`,
                        // url: `http://39.105.150.149:8042/wado?requestType=WADO&studyUID=${studyUID}&seriesUID=${seriesUID}&objectUID=${instance}&contentType=application/dicom`,
                    },
                    responseType: 'blob' // 确保响应类型为Blob
                  }).then((res) => {
                    let image = res
                    imageIdref.current.push(image);
                });
              });
              // 等待所有的Promise完成
              await Promise.all(promises);
              // 打印所有Instance UID
              console.log('All imageIdref UIDs:', imageIdref.current);

              const filesWithInstanceNumbers = [];
              for (let i = 0; i < imageIdref.current.length; i++) {
                  const reader = new FileReader();
                  const curFile = imageIdref.current[i];

                  reader.onload = async (event) => {
                      const arrayBuffer = event.target.result;
                      const instanceNumber = parseDicomFile(arrayBuffer);
                      filesWithInstanceNumbers.push({ instanceNumber, file: curFile });
                      // 如果已经处理完所有文件，则进行排序和获取文件列表
                      if (filesWithInstanceNumbers.length === imageIdref.current.length) {
                          // 按 Instance Number 属性从小到大排序
                          filesWithInstanceNumbers.sort((a, b) => a.instanceNumber - b.instanceNumber);
      
                          // 获取排序后的文件列表
                          const sortedFiles = filesWithInstanceNumbers.map(item => item.file);
                          console.log('sortedFiles', sortedFiles);

                          setDicom(sortedFiles);
                          const imageIds = [];
                          for (let i = 0; i < sortedFiles.length; i++) {
                              imageIds[i] = wadouri.fileManager.add(sortedFiles[i]);
                          }
                          console.log('imageIds', imageIds);
                          loadImageStack(imageIds);
                      }
                  };
                  reader.readAsArrayBuffer(curFile);
              }
          })
        } catch (error) {
          message.error('提交失败!');
          console.error('Error:', error);
          // 在这里处理错误
          return ;
        }
      };

      const getFile = async () => {
        const response = await request.post("/execute", {
            "script1_path": "/workspace/run_1.sh",
            "script2_path": "/workspace/pythonProject/test/run_2.sh"
        }); 
        if (response.error) {
            message.warning(response.error);
        } else {
            uploadTxt();
            uploadCsv();
            message.success('上传成功，且已经返回数据，可上传dicom文件夹。');
        }
        setLoading(false);
      }
    

    const layoutStyle = {
        borderRadius: 0,
        overflow: 'hidden',
        width: '100%',
        maxWidth: '100%',
        height: '100vh',
      };
    const headerStyle = {
        textAlign: 'center',
        color: '#fff',
        height: '10vh',
        minHeight: '185px',
        maxHeight: 'auto',
        position: 'relative',
        backgroundColor: '#031c4a',
        // backgroundColor: '#f9f7f7',
      };
    const contentStyle = {
        textAlign: 'center',
        minHeight: 120,
        lineHeight: '90%',
        color: '#fff',
        width: '100%',
      };
    const siderStyle = {
        textAlign: 'left',
        backgroundColor: '#090b28',
        position: 'relative',
      };
    const sliderTopStyle = {
        height: '65%',
        overflow: 'auto',
        color: '#808080',
    };
    const sliderBottomStyle = {
        // textAlign: 'right',
        minHeight: '86px',
        height: '35%',
        // backgroundColor: '#0958d9',
        overflow: 'auto',
        color: '#e1e8f5'
    };

    const buttonStyle = {
        position: 'absolute',
        right: '10px',
        bottom: '10px',
    };

    return (
        <Spin spinning={loading} tip="正在执行，请等待" wrapperClassName="spin-overlay">
        {contextHolder}
        <Layout style={layoutStyle}>
            <Header style={headerStyle}>
            <h1 className={"title-top"}>胸 部 CT 肺 结 节 诊 断 系 统</h1>
                <div className={'logo-left-top'}>
                    <Image src='zghydx.png'></Image>
                </div>
                <div className={"center-tab"}>
                {/*file upload*/}
                <Tabs defaultActiveKey="1"
                centered className={"custom-tab"} tabBarStyle={{ borderBottom: 'unset', color: 'white' }}
                    items={[{
                        label: `上传文件`,
                        key: '1',
                        children: (    
                        <div>
                        {/*tools*/}
                        <Form onFinish={handleSubmit} layout="inline">
                            <Form.Item
                            label={<span className="custom-label">CT号</span>}
                            name="ctNumber"
                            rules={[{ required: true, message: '请输入CT号' }]}
                            >
                            <Input
                                value={ctNumber}
                                onChange={(e) => setCtNumber(e.target.value)}
                            />
                            </Form.Item>
                            <Form.Item>
                            <Button htmlType="submit">
                                提交
                            </Button>
                            </Form.Item>
                        </Form>
                        </div>
                    ),
                      }, {
                        label: `操作`,
                        key: '2',
                        children: (<div>
                            <Button onClick={() => {
                                handleToolMenuClick({key: cornerstoneTools.PanTool.toolName})
                            }} style={{marginRight: '5px'}}>
                                平移
                            </Button>
                            <Button onClick={() => {
                                handleToolMenuClick({key: cornerstoneTools.ZoomTool.toolName})
                            }} style={{marginRight: '5px'}}>
                                缩放
                            </Button>
                            <Select
                                defaultValue={0}
                                style={{ width: 220, marginRight: '5px' }}
                                onChange={handleWWWC}
                                options={[
                                    { value: 0, label: '原始窗(WW:1500, WL:-450)' },
                                    { value: 1, label: '肺窗(WW:1500, WL:-600)' },
                                    { value: 2, label: '骨窗(WW:1500, WL:300)' },
                                    { value: 3, label: '纵隔窗(WW:350, WL:40)'},
                                    { value: 4, label: '肺窗2(WW:1700, WL:-500)'},
                                    { value: 5, label: '腹窗(WW:400, WL:40)'},
                                    { value: 6, label: '血管(WW:600, WL:300)'},
                                    { value: 7, label: '脑窗(WW:80, WL:40)'},
                                ]}
                                />
            
                            <Button onClick={() => {
                                handleToolMenuClick({key: cornerstoneTools.WindowLevelTool.toolName})
                            }} style={{marginRight: '5px'}}>
                                自定义窗宽窗位
                            </Button>
                            <Button onClick={toggleShowRect} style={{marginRight: '5px'}}>
                                {pointRectShowState === 'show' ? '隐藏肺结节' : '展示肺结节'}
                            </Button>
                            <Button onClick={handleReset} style={{marginRight: '5px'}}>恢复初始样式</Button>
                            <Dropdown menu={{items: menuTools, onClick: handleToolMenuClick}} style={{marginRight: '5px'}}>
                                <a onClick={e => e.preventDefault()}>
                                    <Space>
                                        测量工具
                                        <DownOutlined />
                                    </Space>
                                </a>
                            </Dropdown>
                        </div>),
                      }]}
                    ></Tabs>
            </div>
                
            
            
            <div className={'logo-right-top'}>
                <Image src='wfsrmyy.png'></Image>
            </div>
            </Header>
            
            <Layout>
                <Content style={contentStyle}>
                <div style={{width: '100%', height: '100%',}}>
                {/*viewport*/}
                <div className={'dicom-viewport-wrapper'}>
                    <div className={'dicom-viewport'} id="content" style={{width: '100%', height: '100%'}}
                        onContextMenu={event => {
                            event.preventDefault();
                        }}
                        onMouseDown={(event) => {
                            event.preventDefault();
                        }}
                    />
                    <div>
                        {
                            dicomBasicInfo &&
                            <div className={'dicom-viewport-overlay-right-top'}>
                                <p>潍坊市人民医院</p>
                                <p>ID:{dicomBasicInfo.patientID}</p>
                                <p>{dicomBasicInfo.patientName}</p>
                                <p>{dicomBasicInfo.patientAge}/{dicomBasicInfo.patientSex}</p>
                                <p>{dicomBasicInfo.patientStudyDate}</p>
                            </div>
                        }
                        <div className={'dicom-viewport-overlay-right-bottom'}>
                            {(currentImageIdIndex + 1) || 1} / {(viewport && viewport.imageIds.length) || 1}
                        </div>
                    </div>
                    {/* <div>
                            <Slider vertical reverse className={'dicom-slider'} min={0} max = {(viewport && (viewport.imageIds.length - 1)) || 1} tooltip={{ open: false }} value={currentImageIdIndex} 
                            onChange={goToPage} />
                        </div> */}
                </div>

            </div>
                </Content>
                
                <Sider width="25%" style={siderStyle}>
                    <div style={sliderTopStyle}>
                        {sortDataRef.current && maxColumnsRef.current && viewport.imageIds.length && <List
                                itemLayout="horizontal"
                                dataSource={sortDataRef.current}
                                renderItem={(item, index) => (
                                <List.Item onClick={() => handleListItemClick(item, index)}>
                                    <List.Item.Meta
                                    style={{ marginLeft: '20px', color: '#e1e8f5' }} 
                                    description={(
                                    <span className="custom-meta-description">
                                    第{item.slice + 1}页 {maxColumnsRef.current[index]} {item.width}mm × {item.height}mm
                                  </span>
                                  )}
                                    />
                                </List.Item>
                                )}
                            />
                        }
                    </div>
                    <hr className={'hr-twill'} />
                    <div style={sliderBottomStyle}>
                        {sortDataRef.current && maxColumnsRef.current && viewport.imageIds.length && 
                        <div style={{ marginLeft: '20px' }}>
                            {csvFileRef.current.length > 0 && (
                                <div>
                                    {renderReportContent()}
                                </div>
                            )}
                            <Button style={buttonStyle} onClick={() => onClickpdf()}>生成检查报告</Button>
                        </div>
                        }
                    </div>
                </Sider>
            </Layout>
        </Layout>
        </Spin>
    );
}

export default StackImages;
